﻿//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;

using ProjectBase.Core;
using ProjectBase.Core.Web;

namespace ProjectBase.Mvc.Models
{
    /// <summary>
    ///     A model for ListView control.
    ///     Properties support paging, sorting, readonly access...
    /// </summary>
    public class ListModel : CoreModel, IListModel
    {
        #region members
        readonly IDictionary<string, object> _additionalDeleteParameters = new Dictionary<string, object>();
        readonly IDictionary<string, object> _additionalParameters = new Dictionary<string, object>();
        Func<string> _actionExpression;
        bool _allowSorting = true;
        Func<string> _controllerExpression;

        string _currentAction = string.Empty;
        string _currentController = string.Empty;
        Func<IFilter> _filterExpression;
        IFilter _filter;
        bool _showDetailAction = true;
        bool _showEditOnLeft = true;
        bool _showCaptionAlways = false;

        #endregion members

        #region IListModel Members
        /// <summary>
        ///     AOP (authorization) filter should (must) set this property
        /// </summary>
        public virtual bool IsReadOnly { get; set; }

        /// <summary>
        ///     Filter containing relevent information for a List (e.g. paging)
        /// </summary>
        public virtual IFilter Filter
        {
            get
            {
                if (_filter.IsNull()
                    && _filterExpression.Is())
                {
                    return _filterExpression.Invoke();
                }
                return _filter;
            }
            set { _filter = value; }
        }

        public virtual void SetFilter(Func<IFilter> filterExpression)
        {
            _filterExpression = filterExpression;
        }

        /// <summary>
        ///     The list of generalized items to be displayed in ListWC.
        ///     Any entity could be transferd to IItemToDisplay
        ///     and therefore ListWC can be implemented only once
        /// </summary>
        public virtual IEnumerable<IItemToDisplay> ItemsToDisplay { get; set; }

        /// <summary>Adjust the ListView rendering with a leading Checkbox or Radio column (or nothing)</summary>
        public virtual RowRenderMode RowRenderMode { get; set; }

        /// <summary>
        ///     True will render Edit link on the Table left side.
        ///     Default is true.
        /// </summary>
        public virtual bool ShowEditOnLeft
        {
            get { return _showEditOnLeft; }
            set { _showEditOnLeft = value; }
        }

        /// <summary>
        ///     True: decorate TD text with anchor, False: only text without navigation is rendered.
        ///     Default is true
        /// </summary>
        public virtual bool ShowDetailAction
        {
            get { return _showDetailAction; }
            set { _showDetailAction = value; }
        }

        /// <summary>
        ///     If set to 'false' Table header does not provide sorting links.
        ///     Default is 'true'.
        /// </summary>
        public virtual bool AllowSorting
        {
            get { return _allowSorting; }
            set { _allowSorting = value; }
        }

        /// <summary>
        ///     Would be 'buttons' for next, previous ... rendered?
        /// </summary>
        public virtual bool HidePagingButtons { get; set; }

        /// <summary>
        ///     Allows to extend the link URL generated for each list row
        ///     with some additional paramters for edit and detail
        ///     (e.g. AopUrlFilterAttribute with asked MasterPage)
        /// </summary>
        public virtual IDictionary<string, object> AdditionalParameters
        {
            get { return _additionalParameters; }
        }

        /// <summary>
        ///     Allows to extend the link URL generated for each list row
        ///     with some additional paramters for delete
        ///     (e.g. AopUrlFilterAttribute with asked MasterPage)
        /// </summary>
        public virtual IDictionary<string, object> AdditionalDeleteParameters
        {
            get { return _additionalDeleteParameters; }
        }

        public virtual string CurrentController
        {
            get
            {
                if (_currentController.IsEmpty()
                    && _controllerExpression.Is())
                {
                    return _controllerExpression.Invoke();
                }
                return _currentController;
            }
            set { _currentController = value; }
        }

        public virtual string CurrentAction
        {
            get
            {
                if (_currentAction.IsEmpty()
                    && _actionExpression.Is())
                {
                    return _actionExpression.Invoke();
                }
                return _currentAction;
            }
            set { _currentAction = value; }
        }

        public virtual void SetCurrentController(Func<string> controllerExpression)
        {
            _controllerExpression = controllerExpression;
        }

        public virtual void SetCurrentAction(Func<string> actionExpression)
        {
            _actionExpression = actionExpression;
        }

        /// <summary>
        ///     If there is non empty value, then edit anchor on List view
        ///     will target this window (list will be displayed in one window
        ///     and detail+edit in another window)
        ///     This value is set to IListModel on every OnBeforeList() operation
        /// </summary>
        public virtual string TargetNameForLink { get; set; }

        /// <summary>
        ///     Caption could be rendered even if there is only one page. Default is false
        /// </summary>
        public virtual bool ShowCaptionAlways
        {
            get { return _showCaptionAlways; }
            set { _showCaptionAlways = value; }
        }

        #endregion
    }
}